<template>
  <a-upload name="file" list-type="picture-card" class="image-uploader" :show-upload-list="false" :action="uploadApi" :headers="{ authorization: token }" :before-upload="beforeUpload" @change="handleChange">
    <img v-if="modelValue" :src="modelValue" :alt="alt" />
    <div v-else>
      <loading-outlined v-if="loading" />
      <plus-outlined v-else />
      <div class="upload-text">{{ placeholder }}</div>
    </div>
  </a-upload>
</template>

<script setup lang="ts">
  import { LoadingOutlined, PlusOutlined } from '@ant-design/icons-vue'
  import { message } from 'ant-design-vue'
  import { ref } from 'vue'

  import { getToken } from '/@/storage'
  const token = getToken() || ''

  const uploadApi = `${import.meta.env.VITE_BASE_API_PATH}/contentFile/upload/V1`

  interface Props {
    modelValue?: string
    alt?: string
    placeholder?: string
    maxSize?: number
  }

  const props = withDefaults(defineProps<Props>(), {
    alt: 'image',
    placeholder: '上传图片',
    maxSize: 10,
  })

  const emit = defineEmits<{
    (e: 'update:modelValue', value: string): void
    (e: 'change', value: string): void
  }>()

  const loading = ref(false)

  const beforeUpload = (file: File) => {
    const isImage = file.type.startsWith('image/')
    if (!isImage) {
      message.error('只能上传图片文件!')
      return false
    }

    const isLtMaxSize = file.size / 1024 / 1024 < props.maxSize
    if (!isLtMaxSize) {
      message.error(`图片大小不能超过 ${props.maxSize}MB!`)
      return false
    }
    return true
  }

  const handleChange = (info) => {
    if (info.file.status === 'uploading') {
      loading.value = true
      return
    }
    if (info.file.status === 'done') {
      message.success('上传成功')
      loading.value = false
      emit('update:modelValue', info.file.response.responseData)
    }
    if (info.file.status === 'error') {
      loading.value = false
      message.error(info.file.response.responseMessage || '上传错误')
    }
  }
</script>

<style lang="less" scoped>
  .image-uploader {
    :deep(.ant-upload) {
      width: 200px;
      height: 120px;
    }

    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    .upload-text {
      margin-top: 8px;
    }
  }
</style>
